package cn.fl.settlement.service.impl;

import cmm.comm.facade.framework.api.ISysDictionaryApiService;
import cmm.comm.facade.framework.dto.SysDictionaryDTO;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.logger.eum.LogExceptionEnum;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.DecimalUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.fl.capital.constant.CapitalConstant;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.framework.constant.DictionaryConstant;
import cn.fl.project.condition.PrjPrdPaySchDQueryCondition;
import cn.fl.project.constant.PrjQuatPrpsConstant;
import cn.fl.project.dto.PrjPrdPaySchDDTO;
import cn.fl.project.service.IPrjPrdPaySchDApiService;
import cn.fl.settle.api.ISettlePaySchDApiService;
import cn.fl.settlement.service.ISettleFeeService;
import cn.fl.settlement.vo.PaySchDSettlePageVO;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class SettleFeeServiceImpl implements ISettleFeeService {

    @Autowired
    private IPrjPrdPaySchDApiService prjPrdPaySchDApiService;
    @Autowired
    private ISysDictionaryApiService sysDictionaryApiService;

    @Autowired
    private ISettlePaySchDApiService settlePaySchDApiService;

    @Override
    public List<PaySchDSettlePageVO> searchSettleItemList(Long applyId, String pInstId) throws BaseException {
        if (applyId == null && StringUtils.isEmpty(pInstId)) {
            throw new BaseException("结清申请记录ID与流程实例ID不能同时为空！");
        }
        List<PrjPrdPaySchDDTO> settleItemList = settlePaySchDApiService.searchSettlePaySchDList(applyId, pInstId);
        List<PaySchDSettlePageVO> returnList = Lists.newArrayList();
        if (CollectionUtils.isEmpty(settleItemList)) {
            return returnList;
        }
        Map<String, String> stlFeeTypCdMap = sysDictionaryApiService.searchGroupToMap(CurrentThreadContext.getCurrentSysCd(),
                CurrentThreadContext.getCurrentOrgCd(),
                DictionaryConstant.CODE_PRJ_QUAT_FEE_SETT_TYP_CD);

        for (PrjPrdPaySchDDTO settleItem : settleItemList) {
            PaySchDSettlePageVO itemVo = new PaySchDSettlePageVO();

            itemVo.setFeeAmt(DecimalUtils.convertFenToYuan(settleItem.getFeeAmt().longValue()));
            itemVo.setCapFlow(settleItem.getCapFlow());
            itemVo.setFeeTypCd(settleItem.getFeeTypCd());
            if (CapitalConstant.CODE_FEE_TYP_CD_S02.equals(settleItem.getFeeTypCd())) {
                itemVo.setFeeTypCdNm("未还利息合计");
            } else if (CapitalConstant.CODE_FEE_TYP_CD_S03.equals(settleItem.getFeeTypCd())) {
                itemVo.setFeeTypCdNm("未还本金合计");
            } else if (CapitalConstant.CODE_FEE_TYP_CD_S05.equals(settleItem.getFeeTypCd())) {
                itemVo.setFeeTypCdNm("逾期罚息合计");
            } else if (DictionaryConstant.CODE_PRJ_QUAT_FEE_SETT_TYP_CD.equals(settleItem.getFeeClsCd())) {
                itemVo.setFeeTypCdNm(stlFeeTypCdMap.get(settleItem.getFeeTypCd()));
            } else if (StringUtils.isNotEmpty(settleItem.getFeeClsCd())
                    && StringUtils.isNotEmpty(settleItem.getFeeTypCd())) {
                SysDictionaryDTO dictionaryDTO = sysDictionaryApiService.getCode(CapitalConstant.SYSCD,
                        CapitalConstant.SYSORG,
                        settleItem.getFeeClsCd(),
                        settleItem.getFeeTypCd());
                if (dictionaryDTO != null) {
                    itemVo.setFeeTypCdNm(dictionaryDTO.getCodeNm());
                }
            }
            returnList.add(itemVo);
        }
        return returnList;
    }

    @Override
    public List<PaySchDSettlePageVO> searchSettleFeeList(PrjPrdPaySchDQueryCondition condition) throws BaseException {
        if (condition.getPaySchId() == null) {
            throw new BaseException("查询参数支付表ID不能为空！");
        }
        condition.setPayPd(0l);
        condition.setFeeClsCd(PrjQuatPrpsConstant.CODE_PRJ_QUAT_FEE_CLS_TYP_SETT);
        condition.setSortName("CRT_TM");
        condition.setSortOrder("DESC");
        List<PrjPrdPaySchDDTO> settleFeeList = prjPrdPaySchDApiService.searchPrjPrdPaySchDList(condition);

        List<PaySchDSettlePageVO> returnList = Lists.newArrayList();
        if (CollectionUtils.isEmpty(settleFeeList)) {
            return returnList;
        }
        Map<String, String> stlFeeTypCdMap = sysDictionaryApiService.searchGroupToMap(CurrentThreadContext.getCurrentSysCd(),
                CurrentThreadContext.getCurrentOrgCd(),
                DictionaryConstant.CODE_PRJ_QUAT_FEE_SETT_TYP_CD);

        for (PrjPrdPaySchDDTO stlFee : settleFeeList) {
            PaySchDSettlePageVO feeVo = new PaySchDSettlePageVO();
            feeVo.setId(stlFee.getId());
            feeVo.setPaySchId(stlFee.getPaySchId());
            feeVo.setFeeTypCd(stlFee.getFeeTypCd());
            if (stlFeeTypCdMap.containsKey(stlFee.getFeeTypCd())) {
                feeVo.setFeeTypCdNm(stlFeeTypCdMap.get(stlFee.getFeeTypCd()));
            }
            feeVo.setFeeAmt(DecimalUtils.convertFenToYuan(stlFee.getFeeAmt().longValue()));
            feeVo.setArAmt(DecimalUtils.convertFenToYuan(stlFee.getArAmt()));
            feeVo.setPaidUpAmt(DecimalUtils.convertFenToYuan(stlFee.getPaidUpAmt()));
            feeVo.setCapFlow(stlFee.getCapFlow());
            feeVo.setFeeClsCd(stlFee.getFeeClsCd());
            feeVo.setIsSysDef(stlFee.getIsSysDef());
            feeVo.setFeeRem(stlFee.getFeeRem());

            returnList.add(feeVo);
        }
        return returnList;
    }

    @Override
    public PaySchDSettlePageVO querySettleFeeById(PrjPrdPaySchDQueryCondition condition) throws BaseException {

        if (condition.getId() == null) {
            throw new BaseException("查询条件：数据主键ID不能为空！");
        }
        if (condition.getPaySchId() == null) {
            throw new BaseException("查询条件：支付表ID不能为空！");
        }
        condition.setPayPd(0l);
        condition.setSortName("PAY_PD");
        condition.setSortOrder("ASC");
        List<PrjPrdPaySchDDTO> settleFeeList = prjPrdPaySchDApiService.searchPrjPrdPaySchDList(condition);
        PaySchDSettlePageVO feeVo = new PaySchDSettlePageVO();
        if (CollectionUtils.isNotEmpty(settleFeeList)) {
            PrjPrdPaySchDDTO stlFee = settleFeeList.get(0);

            feeVo.setId(stlFee.getId());
            feeVo.setPaySchId(stlFee.getPaySchId());
            feeVo.setFeeTypCd(stlFee.getFeeTypCd());
            feeVo.setFeeAmt(DecimalUtils.convertFenToYuan(stlFee.getFeeAmt().longValue()));
            feeVo.setCapFlow(stlFee.getCapFlow());
            feeVo.setFeeClsCd(stlFee.getFeeClsCd());
            feeVo.setIsSysDef(stlFee.getIsSysDef());
            feeVo.setFeeRem(stlFee.getFeeRem());
        }
        return feeVo;
    }

    @Override
    public void addSettleFeeFlow(String pInstId, PrjPrdPaySchDDTO entity) throws BaseException {
        try {
            if (entity.getPaySchId() == null) {
                throw new BaseException("支付表ID不能为空！");
            }
            if (StringUtils.isEmpty(entity.getFeeTypCd())) {
                throw new BaseException("费用类型不能为空！");
            } else {
                // 设置资金流向
                entity.setCapFlow(deduceCapFlow(entity.getFeeTypCd()));
            }
            if (entity.getFeeAmt() == null) {
                throw new BaseException("新增费用项金额不能为空！");
            } else {
                entity.setArAmt(entity.getFeeAmt().longValue());
                entity.setPaidUpAmt(0l);
            }
            if (StringUtils.isEmpty(entity.getCapFlow())) {
                throw new BaseException("费用资金流向不能为空！");
            }
            // RPJ0040
            entity.setFeeClsCd(PrjQuatPrpsConstant.CODE_PRJ_QUAT_FEE_CLS_TYP_SETT);
            entity.setPayPd(0);
            entity.setIsFixedAmt(BaseConstant.IS_YESNO_YES);
            entity.setCntWayCd(PrjQuatPrpsConstant.CODE_PRJ_QUAT_CNT_WAY_OTH);
            entity.setIsDel(BaseConstant.IS_YESNO_NO);
            entity.setIsSysDef(BaseConstant.IS_YESNO_NO);
            entity.setIsModify(BaseConstant.IS_YESNO_YES);
            entity.setCrtUsrId(CurrentThreadContext.getCurrentUserId());
            entity.setCrtTm(new Date());
            entity.setMdfUsrId(CurrentThreadContext.getCurrentUserId());
            entity.setMdfTm(new Date());
            settlePaySchDApiService.addSettleFeeFlow(pInstId, entity);
        } catch (BaseException e) {
            BaseLogUtils.newLogger("操作人{0}新增结清费用项业务异常！", CurrentThreadContext.getCurrentUserName()).setThrowable(e).error(LogExceptionEnum.COMMON_CODE_0002);
            throw e;
        } catch (Exception e) {
            BaseLogUtils.newLogger("操作人{0}新增结清费用项系统异常！", CurrentThreadContext.getCurrentUserName()).setThrowable(e).error(LogExceptionEnum.COMMON_CODE_0002);
            throw e;
        }
    }

    @Override
    public void modifySettleFeeFlow(String pInstId, PrjPrdPaySchDDTO entity) throws BaseException {
        try {
            if (entity.getId() == null) {
                throw new BaseException("待修改的结清费用项ID不能为空！");
            }
            if (entity.getPaySchId() == null) {
                throw new BaseException("支付表ID不能为空！");
            }
            if (StringUtils.isEmpty(entity.getFeeTypCd())) {
                throw new BaseException("费用类型不能为空！");
            } else {
                // 设置资金流向
                entity.setCapFlow(deduceCapFlow(entity.getFeeTypCd()));
            }
            if (entity.getFeeAmt() == null) {
                throw new BaseException("新增费用项金额不能为空！");
            } else {
                entity.setArAmt(entity.getFeeAmt().longValue());
                entity.setPaidUpAmt(0l);
            }
            if (StringUtils.isEmpty(entity.getCapFlow())) {
                throw new BaseException("费用资金流向不能为空！");
            }
            entity.setMdfUsrId(CurrentThreadContext.getCurrentUserId());
            entity.setMdfTm(new Date());
            settlePaySchDApiService.modifySettleFeeFlow(pInstId, entity);
        } catch (BaseException e) {
            BaseLogUtils.newLogger("操作人{0}修改结清费用项业务异常！", CurrentThreadContext.getCurrentUserName()).setThrowable(e).error(LogExceptionEnum.COMMON_CODE_0002);
            throw e;
        } catch (Exception e) {
            BaseLogUtils.newLogger("操作人{0}修改结清费用项系统异常！", CurrentThreadContext.getCurrentUserName()).setThrowable(e).error(LogExceptionEnum.COMMON_CODE_0002);
            throw e;
        }
    }

    @Override
    public void removeSettleFeeFlow(String pInstId, PrjPrdPaySchDDTO entity) throws BaseException {
        try {
            if (entity.getId() == null) {
                throw new BaseException("待删除的结清费用项ID不能为空！");
            }
            if (entity.getPaySchId() == null) {
                throw new BaseException("支付表ID不能为空！");
            }
            if (StringUtils.isEmpty(entity.getFeeTypCd())) {
                throw new BaseException("费用类型不能为空！");
            }
            entity.setMdfUsrId(CurrentThreadContext.getCurrentUserId());
            entity.setMdfTm(new Date());
            settlePaySchDApiService.removeSettleFeeFlow(pInstId, entity);
        } catch (BaseException e) {
            BaseLogUtils.newLogger("操作人{0}删除结清费用项ID={1}业务异常！", CurrentThreadContext.getCurrentUserName(), entity.getId())
                    .setThrowable(e).error(LogExceptionEnum.COMMON_CODE_0002);
            throw e;
        } catch (Exception e) {
            BaseLogUtils.newLogger("操作人{0}删除结清费用项ID={1}系统异常！", CurrentThreadContext.getCurrentUserName(), entity.getId())
                    .setThrowable(e).error(LogExceptionEnum.COMMON_CODE_0002);
            throw e;
        }
    }

    /**
     * 推断结清费用项资金流向
     * @param feeTypCd
     * @return
     * @throws BaseException
     */
    public String deduceCapFlow(String feeTypCd) throws BaseException {
        SysDictionaryDTO dictionaryDTO = sysDictionaryApiService.getCode(CapitalConstant.SYSCD,
                CapitalConstant.SYSORG,
                DictionaryConstant.CODE_PRJ_QUAT_FEE_SETT_TYP_CD,
                feeTypCd);
        if (dictionaryDTO == null) {
            throw new BaseException("非法的结清费用类型！");
        }
        return dictionaryDTO.getCodeAttr1();
    }


}
